package com.wbc.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 关闭指定端口的程序
 * @Author: wangbingchen
 * @CreateTime: 2024-01-04
 */
public class ShutdownWinExeUtil {
    public static void main(String[] args) throws IOException {
        //关闭指定端口
//        shutdownExeByPort(3306);
        //查看指定端口是否被占用
//        boolean b = isActivePort(3306);
//        System.out.println(b);
        //查看指定端口占用的程序
//        String name = findExeNameByPort(6379);
//        System.out.println(name);

    }

    private static String findExeNameByPid(String pid) {
        List<TaskListBean> tasklist = getTasklist();
        for (TaskListBean taskListBean : tasklist) {
            if(pid.equals(taskListBean.getPid())){
                return taskListBean.getExeName();
            }
        }
        return null;
    }


    /**
     * 通过 cmd 命令 获取 javaMaplist对象
     * @param cmd
     * @return
     */
    private static List<List<String>> cmdToMap(String cmd) {
        List<List<String>> reList = new ArrayList<>();
        try {
            Process cmdRes = Runtime.getRuntime().exec(cmd);
            InputStream inputStream = cmdRes.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("GBK")));
            bufferedReader.readLine();
            bufferedReader.readLine();
            bufferedReader.readLine();
            bufferedReader.readLine();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
//                beanList.add(new NetstatBean(toTrim(line)));
                String trim = toTrim(line);
                String[] split = trim.split(" ");
                List<String> lineString = new ArrayList<>(Arrays.asList(split));
                reList.add(lineString);
            }
        }catch (Exception e){
            throw new RuntimeException("运行错误");
        }

        return reList;
    }

    public static String findExeNameByPort(int port) {
        List<String> pidList = getPidList(String.valueOf(port));
        if(pidList.size() == 0){
            throw new RuntimeException("端口未占用");
        }
        String pid = pidList.get(0);
        return findExeNameByPid(pid);
    }

    /**
     * 查看端口是否被占用
     * @param port
     * @return
     */
    public static boolean isActivePort(Integer port) {
        List<String> pidList = getPidList(String.valueOf(port));
        return pidList.size()>0;
    }

    /**
     * 关闭指定端口的程序
     * @param port 3306
     */
    public static void shutdownExeByPort(Integer port) {
        List<String> pidList = getPidList(String.valueOf(port));
        shutdownExeByPidList(pidList);
    }





    private static void shutdownExeByPidList(List<String> pidList) {
        //关闭指定 pid
        for (String pid : pidList) {
            shutdownExeByPid(pid);
        }
    }

    private static void shutdownExeByPid(String pid) {
        try {
            Runtime.getRuntime().exec("taskkill /F /pid "+pid);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    private static List<String> getPidList(String port) {
        //获取指定端口的 pidlist
        List<String> pidList = new ArrayList<>();
        for (NetstatBean netstatBean : getNetstatANO()) {
            if(port.equals(netstatBean.getLocalAddressPort())){
                pidList.add(netstatBean.getPid());
            }
        }
        return pidList;
    }
    /**
     * 获取 指定命令 netstat -ano 的对象集合
     * @return
     */
    private static List<TaskListBean> getTasklist() {
        List<List<String>> listList = cmdToMap("tasklist");
        List<TaskListBean> beanList = new ArrayList<>();
        for (List<String> strings : listList) {
            if(strings.size()==6){
                beanList.add(new TaskListBean(strings));
            }
        }
        return beanList;
    }

    /**
     * 获取 指定命令 netstat -ano 的对象集合
     * @return
     */
    private static List<NetstatBean> getNetstatANO() {
        List<List<String>> listList = cmdToMap("netstat -ano");
        List<NetstatBean> beanList = new ArrayList<>();
        for (List<String> strings : listList) {
            beanList.add(new NetstatBean(strings));
        }
        return beanList;
    }

    /**
     * 统一格式化 字符串
     * @param str
     * @return
     */
    private static String toTrim(String str) {
        String trim = str.trim();
        while (true){
            String cacheStr = trim;
            trim = trim.replace("  "," ");
            if(cacheStr.equals(trim)){
                break;
            }
        }
        return trim;
    }
}
class TaskListBean{
    private String exeName; //映像名称
    private String pid; //PID
    private String sessionName; //会话名
    private String session; //会话#
    private String memoryUsage; //内存使用

    public String getExeName() {
        return exeName;
    }

    public String getPid() {
        return pid;
    }

    public TaskListBean(List<String> list) {
        exeName = list.get(0);
        pid = list.get(1);
        sessionName = list.get(2);
        session = list.get(3);
        memoryUsage = list.get(4)+list.get(5);

    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("TaskListBean{");
        sb.append("exeName='").append(exeName).append('\'');
        sb.append(", pid='").append(pid).append('\'');
        sb.append(", sessionName='").append(sessionName).append('\'');
        sb.append(", session='").append(session).append('\'');
        sb.append(", memoryUsage='").append(memoryUsage).append('\'');
        sb.append('}');
        return sb.toString();
    }
}
class NetstatBean{
    private String agreement;
    private String LocalAddress;
    private String LocalAddressIP;
    private String LocalAddressPort;
    private String externalAddress;
    private String state;
    private String pid;

    public NetstatBean(List<String> strings) {
        agreement = strings.get(0);
        LocalAddress = strings.get(1);
        int i = LocalAddress.lastIndexOf(":");
        LocalAddressIP = LocalAddress.substring(0,i);
        LocalAddressPort = LocalAddress.substring(++i);
        externalAddress = strings.get(2);
        if("UDP".equals(agreement)){
            pid = strings.get(3);
        }
        if("TCP".equals(agreement)){
            state = strings.get(3);
            pid = strings.get(4);
        }
    }

    public String getLocalAddressPort() {
        return LocalAddressPort;
    }

    public String getPid() {
        return pid;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("NetstatBean{");
        sb.append("agreement='").append(agreement).append('\'');
        sb.append(", LocalAddress='").append(LocalAddress).append('\'');
        sb.append(", LocalAddressIP='").append(LocalAddressIP).append('\'');
        sb.append(", LocalAddressPort='").append(LocalAddressPort).append('\'');
        sb.append(", externalAddress='").append(externalAddress).append('\'');
        sb.append(", state='").append(state).append('\'');
        sb.append(", pid='").append(pid).append('\'');
        sb.append('}');
        return sb.toString();
    }
}